package Goverment;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Calendar;

public class Go {
	public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
		try 
		  {
		     /* Server opzetten */
			 ServerSocket listensocket=new ServerSocket(1234);
			 while(true) {
				 System.out.println("Waiting for client");
				 Socket client=listensocket.accept();
				 System.out.println("Client accepted");
				 BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
	
			     /* Wachten op input */
			     System.out.println("Available = " + client.getInputStream().available());
			     while(client.getInputStream().available() == 0 ) {
			    	 Thread.sleep(100);
			    	 System.out.println("Nothing to read :)");
			     }
			     
			     /* Starten met Lezen */
			     String s = reader.readLine();
			     System.out.println("Read: " + s);
			     
			     /* Input met commandos vergelijken */
			     if(s.equals("RevalidationRequest")) {
			    	 
			    	 System.out.println("Sending time");
	
			    	 byte[] data = GetCurrentDate();
			    	 
	//				 http://www.asciiflow.com/
	//		    	 +------+-----+---+----+------+------+
	//		    	 | year |month|day|hour|minute|second|
	//		data  =  |------|-----|---|----|------|------|
	//		    	 | b0 b1| b2  |b3 | b4 |  b5  |  b6  |
	//		    	 +------+-----+---+----+------+------+
				       	 
			    	 byte[] signature = signData(data);
			    	 
			    	 byte[] total = generateMessage(data, signature);
			    	 
			    	 client.getOutputStream().write(total);
			         client.getOutputStream().flush();
			     }
			     client.close();
			  }	//end while(true)
		  }	//end try{...
		  catch (Exception e)
		  {
		     System.out.println(e);
		  }
		  
	}

	private static byte[] generateMessage(byte[] data, byte[] signature) {
		byte[] tail1 = ( "-_@@_-" + data.length + "-_@@_-" + signature.length + "-_@@_-").getBytes();
        byte[] total = new byte[tail1.length + signature.length + data.length]; //arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 
        
        System.arraycopy( data, 0 ,total, 0, data.length);
        System.arraycopy( signature, 0, total, data.length, signature.length);
        System.arraycopy( tail1, 0, total, data.length + signature.length, tail1.length);
        System.out.println("Message: ");
		for(byte b : total) {
			System.out.print(b + " ");
		}
		System.out.println();
		return total;
	}

	@SuppressWarnings("deprecation")
	public static byte[] GetCurrentDate() throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(bos);

		Calendar c = Calendar.getInstance();

		out.writeShort(c.get(Calendar.YEAR));
		out.writeByte(c.get(Calendar.MONTH));
		out.writeByte(c.get(Calendar.DAY_OF_MONTH));
		out.writeByte(c.get(Calendar.HOUR_OF_DAY));
		out.writeByte(c.get(Calendar.MINUTE));
		out.writeByte(c.get(Calendar.SECOND));
		byte[] int_bytes = bos.toByteArray();
		bos.close();
		return int_bytes;
	}
	
	public static byte[] signData(byte[] data) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
		/* Private key geoverment inlezen  */
		byte[] priv_government = readFile("secure_files/private_government.key");
		EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(priv_government);
        KeyFactory generator = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = generator.generatePrivate(privateKeySpec);
        
		/* Get Signature */
   	 	Signature rsa = Signature.getInstance("SHA1withRSA");
        rsa.initSign(privateKey);
        
        /* Sign data */
        rsa.update(data);	
        return rsa.sign(); 
	}

	public static byte[] readFile(String filename) {
		File file = new File(filename);
		byte[] fileContent = null;
		try {
			FileInputStream myCert = new FileInputStream(filename);
			fileContent = new byte[(int) file.length()];
			myCert.read(fileContent);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fileContent;
	}
}
